package com.atguigu.gmall.pms.service.impl;

import com.atguigu.gmall.pms.entity.*;
import com.atguigu.gmall.pms.feign.SmsClient;
import com.atguigu.gmall.pms.service.*;
import com.atguigu.gmall.pms.vo.BaseAttrVo;
import com.atguigu.gmall.pms.vo.SkuVo;
import com.atguigu.gmall.pms.vo.SpuVo;
import com.atguigu.gmall.sms.dto.SkuSalesDto;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import io.jsonwebtoken.lang.Collections;
//import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.gmall.common.bean.PageResultVo;
import com.atguigu.gmall.common.bean.PageParamVo;

import com.atguigu.gmall.pms.mapper.SpuMapper;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;


@Service("spuService")
public class SpuServiceImpl extends ServiceImpl<SpuMapper, SpuEntity> implements SpuService {
    @Autowired
    SpuAttrValueService spuAttrValueService;
    @Autowired
    SpuDescService spuDescService;
    @Autowired
    SkuService skuService;
    @Autowired
    RabbitTemplate rabbitTemplate;
    @Override
    public PageResultVo queryPage(PageParamVo paramVo) {
        IPage<SpuEntity> page = this.page(
                paramVo.getPage(),
                new QueryWrapper<SpuEntity>()
        );

        return new PageResultVo(page);
    }
    //http://api.gmall.com/pms/spu/category/0?t=1662512469165&pageNum=1&pageSize=10&key=7
    //0 希望查询所有
    // categoryid条件检索时   和  id name中包含key的关系？
    // categortid=225 and (id like '%key%' or  name like '%key%')
    //SELECT id,name,category_id,brand_id,publish_status,create_time,update_time
    // FROM pms_spu WHERE (category_id = ? AND id LIKE ?  OR name LIKE ? ) LIMIT ?
    @Override
    public PageResultVo querySpusByCid(String categoryId, PageParamVo paramVo) {
        LambdaQueryWrapper<SpuEntity> queryWrapper = new LambdaQueryWrapper<>();
        String key = paramVo.getKey();//查询条件
        if(!StringUtils.equals(categoryId , "0")){
            queryWrapper.eq(SpuEntity::getCategoryId , categoryId);
        }
        if(StringUtils.isNotBlank(key)){
            //key是查询 spu的条件
            //标题 或者 id只要包含key的 就符合要求
            //(category_id = ? AND (id LIKE ? OR name LIKE ?))
            queryWrapper.and(t->t.like(SpuEntity::getId , key)
                        .or().like(SpuEntity::getName , key));
        }
        IPage<SpuEntity> page = this.page(paramVo.getPage(), queryWrapper);
        return new PageResultVo(page);
    }
    /*
        有多个sql写操作：
            他们都属于一个业务的操作，我们希望要么一起成功要么一起失败，可以使用事务控制
Transactional:
            原理是aop
            对调用的目标方法进行了扩展
            方法调用前开启事务
            方法调用时它对方法调用进行了trycatch，如果进入到catch中 回滚
            如果try的最后一行代码能执行到 则提交事务

     */
//    @GlobalTransactional
    @Transactional
    @Override
    public void saveSpuVo(SpuVo spuVo) {
        //1、保存spu的数据
        Long spuId = saveSpu(spuVo); //事务使用saveSpuVo的事务   回滚
        //2、保存spu的商品详情图地址
        spuDescService.saveSpuDesc(spuVo, spuId); //事务saveSpuDesc自己创建     提交
        //3、保存spu的基本属性
        spuAttrValueService.saveSpuBaseAttrs(spuVo, spuId);//2
        //4、保存sku集合
        skuService.saveSkus(spuVo, spuId);


        try {
            Map<String,String> map = new HashMap<>();
            map.put("spuId" , spuId+"");
            map.put("operate" , "1");// 1代表新增spu
            //发送消息到mq：
            rabbitTemplate.convertAndSend("gmall.goods.exchange"
            ,"goods.save" , map);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //1、保存spu
    @Transactional
    public Long saveSpu(SpuVo spuVo) {
        SpuEntity spuEntity = new SpuEntity();
        BeanUtils.copyProperties(spuVo , spuEntity);
        spuEntity.setCreateTime(new Date());
        spuEntity.setUpdateTime(new Date());
        this.save(spuEntity);
        //获取新增成功的spu的id
        return spuEntity.getId();
    }
    //2、保存spudesc

    //3、保存spuattrvalues

    //4、保存sku







}